import jwt

from typing import Optional
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer
import requests
import json
import jwt
from datetime import datetime, timedelta
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
from base64 import b64encode, b64decode


class PublicService:
    __instance = None

    ACCESS_TOKEN_EXPIRE_MINUTES = 30
    reusable_oauth2 = HTTPBearer(
        scheme_name='Authorization'
    )

    # 初始化RSA密钥对
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )
    public_key = private_key.public_key()

    @classmethod
    def getPublicKey(cls):
        pem = cls.public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        )
        return {"publicKey": b64encode(pem).decode('utf-8')}

    
    @staticmethod
    def requestGithub(userName:str):
        response = requests.get(f"https://api.github.com/search/users?q={userName}")
        if (response.status_code == 200):
            return response.json()
        else:
            return None

    @classmethod
    def decode_userInfo(cls, data):
        decrypted_email = cls.private_key.decrypt(
            b64decode(data.username.encode('utf-8')),
            padding.PKCS1v15()
        )
        decrypted_password = cls.private_key.decrypt(
            b64decode(data.password.encode('utf-8')),
            padding.PKCS1v15()
        )
        return decrypted_email, decrypted_password

        
    @staticmethod
    def create_access_token(data: dict, expires_delta: timedelta = None):
        to_encode = data.copy()
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(minutes=15)
        to_encode.update({"exp": expire})
        encoded_jwt = jwt.encode(to_encode, 'CAIXPROMISE', algorithm='HS256')
        return encoded_jwt